using System;
using System.Collections.Generic;
using Jalal.Library.DataStructure;
using BCGC.BLL.Helper;
using BCGC.DAL;
using System.Transactions;
using Jalal.Library.Data;
using System.Data;
namespace BCGC.BLL.BusinessObject.Poll
{
    public class PollQuestion
    {
        private int id;
        public int Id
        {
            get
            {
                return id;
            }
        }

        private String question;
        public String Question
        {
            get
            {
                return question;
            }
            set
            {
                question = value;
            }
        }

        private int totalVotes;
        public int TotalVotes
        {
            get
            {
                return totalVotes;
            }
        }

        private ReadWriteCustomCollection<PollAnswer> answers;
        public ReadOnlyCustomCollection<PollAnswer> Answers
        {
            get 
            {
                if (answers != null)
                    return answers.ReadOnlyClone();
                else
                    return null;
            }
        }

        private DateTime createDateTime;
        public DateTime CreateDateTime
        {
            get
            {
                return createDateTime;
            }
        }

        private bool _isCurrentPollQuestion;
        public bool IsCurrentPollQuestion
        {
            get { return this._isCurrentPollQuestion; }
            set { this._isCurrentPollQuestion = value; }
        }

        private int _answerCount;
        public int AnswerCount
        {
            get { return this._answerCount; }
            set { this._answerCount = value; }
        }

        public PollQuestion()
        {
            this.id = 0;
            this.question = string.Empty;
            this.totalVotes = 0;
            this.createDateTime = DateTime.Now;
            this.answers = null;
            this._isCurrentPollQuestion = false;
            this._answerCount = 0;
        }

        public PollQuestion(int id, string question)
        {
            this.id = id;
            this.question = question;
            this.totalVotes = 0;
            this.createDateTime = DateTime.Now;
            this.answers = null;
            this._isCurrentPollQuestion = false;
            this._answerCount = 0;
        }

        public PollQuestion(DataRow dataRow)
        {
            if (dataRow != null)
            {
                if (dataRow.Table.Columns.Contains("Id"))
                    this.id = (int)dataRow["Id"];
                if (dataRow.Table.Columns.Contains("Question"))
                    this.question = (string)dataRow["Question"];
                if (dataRow.Table.Columns.Contains("TotalVotes"))
                    this.totalVotes = (int)dataRow["TotalVotes"];
                if (dataRow.Table.Columns.Contains("CreateDateTime"))
                    this.createDateTime = (DateTime)dataRow["CreateDateTime"];

                this.answers = null;

                if (dataRow.Table.Columns.Contains("IsCurrentPollQuestion"))
                    this._isCurrentPollQuestion = (bool)dataRow["IsCurrentPollQuestion"];
                if (dataRow.Table.Columns.Contains("AnswerCount"))
                    this._answerCount = (int)dataRow["AnswerCount"];
            }
            else
            {
                this.id = 0;
                this.question = string.Empty;
                this.totalVotes = 0;
                this.createDateTime = DateTime.Now;
                this.answers = null;
                this._isCurrentPollQuestion = false;
                this._answerCount = 0;
            }
        }

        public static PollQuestion Create(String question, List<String> answers)
        {
            DataFactory.GetDataMiner().BeginTransaction(false);

            PollQuestion pollQuestion = null;

            try
            {
                int questionId = PollData.CreatePollQuestion(question, answers.Count);
                pollQuestion = new PollQuestion(questionId, question);

                int i = 0;
                pollQuestion.answers = new ReadWriteCustomCollection<PollAnswer>();
                foreach (string answer in answers)
                {
                    PollAnswer pollAnswer = PollAnswer.Create(answer, i++, pollQuestion.Id);
                    pollQuestion.answers.Add(pollAnswer);
                }
                DataFactory.GetDataMiner().CommitTransaction();
            }
            catch(Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                pollQuestion = null;
                throw ex;
            }

            return pollQuestion;
        }

        public static void Delete(PollQuestion questionToDelete)
        {
            List<int> deleteId = new List<int>();
            deleteId.Add(questionToDelete.Id);
            Delete(deleteId);
        }

        public static void Delete(List<PollQuestion> questionsToDelete)
        {
            List<int> deleteId = new List<int>();
            foreach (PollQuestion questionToDelete in questionsToDelete)
            {
                deleteId.Add(questionToDelete.Id);
            }
            Delete(deleteId);
        }

        public static void Delete(List<int> questionIdsToDelete)
        {
            DataFactory.GetDataMiner().BeginTransaction(false);

            try
            {
                int deletedItemCount = PollData.DeleteQuestions(questionIdsToDelete);
                if (deletedItemCount == questionIdsToDelete.Count)
                    DataFactory.GetDataMiner().CommitTransaction();
                else
                    throw new Exception("Failed to delete all items");
            }
            catch (Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                throw ex;
            }
        }

        public void Delete()
        {
            List<int> deleteId = new List<int>();
            deleteId.Add(this.Id);
            Delete(deleteId);
        }

        public void Update()
        {
            throw new System.Exception("Not implemented");
        }

        public int IncreaseVoteCount()
        {
            return this.totalVotes++;
        }

        public void ResetVoteCount()
        {
            this.totalVotes = 0;
        }

        public void AddAnswer(PollAnswer newAnswer)
        {
            if (this.answers == null)
                this.answers = new ReadWriteCustomCollection<PollAnswer>();
            this.answers.Add(PollAnswer.Create(newAnswer.Answer, newAnswer.DisplayOrder, newAnswer.QuestionId)); 
        }

        public void RemoveAnswer(PollAnswer answerToRemove)
        {
            if (this.answers != null)
            {
                this.answers.Remove(answerToRemove);
                PollAnswer.Delete(answerToRemove);
            }
        }

        public void RemoveAnswer(int idToRemoveAnswer)
        {
            if (this.answers != null)
            {
                foreach (PollAnswer answer in this.answers)
                {
                    if (answer.Id == idToRemoveAnswer)
                    {
                        this.answers.Remove(answer);
                        List<int> idToDelete = new List<int>();
                        idToDelete.Add(idToRemoveAnswer);
                        PollAnswer.Delete(idToDelete);
                    }
                }
            }
        }

        public static ReadWriteCustomCollection<PollQuestion> GetQuestionsBySearch(List<string> keywords)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);

            DataTable questions = PollData.GetAllQuestions();
            ReadWriteCustomCollection<PollQuestion> filteredQuestions = new ReadWriteCustomCollection<PollQuestion>();

            if (keywords != null)
            {
                foreach (DataRow row in questions.Rows)
                {
                    foreach (string keyword in keywords)
                    {
                        if (row["Question"] != null && row["Question"].ToString() == keyword)
                        {
                            filteredQuestions.Add(new PollQuestion(row));
                            break;
                        }
                    }
                }
            }
            else
            {
                foreach (DataRow row in questions.Rows)
                {
                    filteredQuestions.Add(new PollQuestion(row));
                }
            }
            DataFactory.GetDataMiner().CommitTransaction();

            return filteredQuestions;
        }

        public static PollQuestion GetPollQuestionById(int id)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            DataTable result = PollData.GetPollQuestionById(id);
            DataFactory.GetDataMiner().CommitTransaction();

            if (result.Rows.Count > 0)
                return new PollQuestion(result.Rows[0]);
            else
                return null;
        }

        public static bool PollQuestionExists(string questionText)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            bool result = (PollData.QuestionTextCount(questionText) > 0);
            DataFactory.GetDataMiner().CommitTransaction();
            return result;
        }
    }
}
